package edu.caece.langprocessor.syntax.parse;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import edu.caece.langprocessor.lexical.tokens.ErrorLexicalToken;
import edu.caece.langprocessor.lexical.tokens.SimpleLexicalToken;
import edu.caece.langprocessor.lexical.tokens.TokenType;
import edu.caece.langprocessor.syntax.Terminal;

public class ShiftReduceActionsTable {
	
	private static final String SPLIT_STR = "~";	
	private Map<Integer, Map<Terminal, Action>> shifReduceActionsMap;
	private Set<String> lexicalVocabulary;
	
	public ShiftReduceActionsTable(Set<String> lexicalVocabulary){
		this.shifReduceActionsMap = new HashMap<Integer, Map<Terminal, Action>>();
		this.lexicalVocabulary = lexicalVocabulary;
	}
	
	public Action getAction(Integer state, Terminal terminal){
		Action a = new NoAction();
		if (this.shifReduceActionsMap.keySet().contains(state)) {
			Map<Terminal, Action> actions = this.shifReduceActionsMap.get(state);
			if (actions.containsKey(terminal))
				a = actions.get(terminal);
		}
		return a;
	}
	
	public void setShiftReduceActionsMapFromStringsList(List<String> list) {

		Action a;
		String[] actionArray;
		Terminal t;

		for (String item : list) {
			actionArray = item.split(SPLIT_STR);
			// primero tomamos el estado
			Integer state = Integer.parseInt(actionArray[0]);
			//TODO Se setea el token correspondiente
			String token = actionArray[1];
			if(this.lexicalVocabulary.contains(token)){
				t = new Terminal(new SimpleLexicalToken(TokenType.StringToTokenType(token), ""));
			} else {
				t = new Terminal(new ErrorLexicalToken(""));
			}
			// Se define la accion a ejecutar
			if (actionArray[2].equals("r")) {
				a = new ReduceAction(Integer.parseInt(actionArray[3]));
			} else if (actionArray[2].equals("s")) {
				a = new ShiftAction(Integer.parseInt(actionArray[3]));
			} else if (actionArray[2].equals("a")) {
				a = new AcceptAction(Integer.parseInt(actionArray[3]));
			} else {
				a = new NoAction();
			}
			// colocamos los datos en el mapa
			if (!this.shifReduceActionsMap.containsKey(state)) {
				this.shifReduceActionsMap.put(state,
						new HashMap<Terminal, Action>());
			}
			this.shifReduceActionsMap.get(state).put(t, a);
		}
	}
}
